﻿using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;

namespace com.yoozoo.gta.Art
{
    public class SetGlobalDitherMatrix : MonoBehaviour
    {
        static void InitMatrix()
        {
            float[] globalDitherMatrix = new float[256];
            GenerateDitherMatrix(ref globalDitherMatrix, 16);
            Shader.SetGlobalFloatArray("GlobalDitherMatrix", globalDitherMatrix);
        }
        /*static SetGlobalDitherMatrix()
        {
            InitMatrix();
        }*/

        private void Awake()
        {
            InitMatrix();
        }

        private static void GenerateDitherMatrix(ref float[] output, int n)
        {
            Assert.IsTrue(Mathf.IsPowerOfTwo(n) && n > 1);
            int log2N = Mathf.RoundToInt(Mathf.Log(n, 2));
            int[,] temp = new int[n, n];
            temp[0, 0] = 0;
            temp[0, 1] = 3;
            temp[1, 0] = 2;
            temp[1, 1] = 1;
            int currentSize = 2;
            for (int i = 1; i < log2N; i++)
            {
                for (int row = 0; row < currentSize; row++)
                {
                    for (int col = 0; col < currentSize; col++)
                    {
                        temp[row, col + currentSize] = temp[row, col] * 4 + 3;
                    }
                }

                for (int row = 0; row < currentSize; row++)
                {
                    for (int col = 0; col < currentSize; col++)
                    {
                        temp[row + currentSize, col] = temp[row, col] * 4 + 2;
                    }
                }

                for (int row = 0; row < currentSize; row++)
                {
                    for (int col = 0; col < currentSize; col++)
                    {
                        temp[row + currentSize, col + currentSize] = temp[row, col] * 4 + 1;
                    }
                }

                for (int row = 0; row < currentSize; row++)
                {
                    for (int col = 0; col < currentSize; col++)
                    {
                        temp[row, col] = temp[row, col] * 4;
                    }
                }

                currentSize *= 2;
            }

            for (int i = 0; i < n * n; i++)
            {
                output[i] = (1f + temp[i / n, i % n]) / (1 + n * n);
            }
        }
    }

    #if UNITY_EDITOR
    [CustomEditor(typeof(SetGlobalDitherMatrix))]
    public class DitherInfo : Editor
    {
        private SetGlobalDitherMatrix _target;
        
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            EditorGUILayout.HelpBox("脚本功能：启动时为一个shader全局变量传递一次数组，用于以下效果：\n" + 
                                    "1、内城屋顶的消失和出现的效果。\n" +
                                    "2、街道主角被顶墙角时相机距离身体较近时角色半透明效果。"
                                            ,MessageType.Info);
        }
    }
    #endif
}